#include "displayer.hh"

#include <GL/glew.h>

Displayer::Displayer (SDL_Surface* screen, Camera* cam):
  screen_ (screen),
  cam_ (cam)
{
}

void
Displayer::draw (const Map* m,
		 const tbb::concurrent_hash_map<int, boost::shared_ptr<Object> >* o,
		 const std::list<Blitable*>& t,
		 const tbb::concurrent_hash_map<int, boost::shared_ptr<Displayable> >& d)
{
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();

  cam_->view ();

  for (tbb::concurrent_hash_map<int, boost::shared_ptr<Object> >::const_iterator it = o->begin ();
       it != o->end (); ++it)
    it->second->dispatch ();

  //ensure map construction in main thread
  if (m->built ())
    m->dispatch ();
  else
  {
    std::cout << "YOUHOUHOUHOU" << std::endl;
    glColor3ub (0, 255, 0);
    Map* mprime = const_cast<Map*> (m);
    mprime->init_bos ();
    mprime->built (true);
  }

  for (tbb::concurrent_hash_map<int, boost::shared_ptr<Displayable> >::const_iterator it = d.begin ();
       it != d.end (); ++it)
  {
    it->second->dispatch ();
  }

  if (t.size ())
  {
    glDisable (GL_DEPTH_TEST);

    glMatrixMode (GL_PROJECTION);
    glPushMatrix ();
    glLoadIdentity ();

    gluOrtho2D (0, 1024, 768, 0);
    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();

    glColor3ub (255, 0, 0);
    glEnable(GL_TEXTURE_2D);
    for (std::list<Blitable*>::const_iterator it = t.begin ();
	 it != t.end (); ++it)
      (*it)->dispatch ();

    glMatrixMode (GL_PROJECTION);

    glPopMatrix ();
    glMatrixMode (GL_MODELVIEW);
    glEnable (GL_DEPTH_TEST);
  }

  glFlush ();
  SDL_GL_SwapBuffers ();
  SDL_Flip (screen_);
}
